
#pragma once

#include <QDomDocument>
#include <QtCore>
#include "dataspecification_global.h"

namespace DataSpecificationGW
{
    /************************************************************************/
    //自定义xml类
    //提供简明的读写接口
    /************************************************************************/
    class DATASPECIFICATIONSHARED_EXPORT XMLDocument : public QObject
    {
    public:
        /************************************************************************/
        //自定义xml类 -- 构造函数
        //输入参数：
        //      root -- XML格式数据，或者根节点名（用于写）
        //      pchCodecName -- 编码名（默认UTF-8）
        //      parent -- 父Object
        //返回参数：
        //      根节点
        /************************************************************************/
        XMLDocument(const QString& root,
            const char* pchCodecName = "utf-8",
            QObject* parent = 0);//构造函数

        ~XMLDocument();//析构函数

        /****************************/
        //节点操作
        /****************************/
        /************************************************************************/
        //自定义xml类 -- 根节点
        //输入参数：
        //      void
        //返回参数：
        //      根节点
        /************************************************************************/
        QDomElement documentElement(void)const
        {
            return m_doc.documentElement();
        }

        /************************************************************************/
        //自定义xml类 -- 子节点
        //输入参数：
        //      name -- 节点名
        //返回参数：
        //      元素列表
        /************************************************************************/
        QList<QDomElement> childElement(const QString& name = QString()) const;

        /************************************************************************/
        //自定义xml类 -- 第一个子节点
        //输入参数：
        //      name -- 节点名
        //返回参数：
        //      节点
        /************************************************************************/
        QDomElement firstChildElement(const QString& name = QString()) const
        {
            return m_element.firstChildElement(name);
        }

        /************************************************************************/
        //自定义xml类 -- 最后一个子节点
        //输入参数：
        //      name -- 节点名
        //返回参数：
        //      节点
        /************************************************************************/
        QDomElement lastChildElement(const QString& name = QString())
        {
            return m_element.lastChildElement(name);
        }

        /************************************************************************/
        //自定义xml类 -- 下一个节点
        //输入参数：
        //      name -- 节点名
        //返回参数：
        //      节点
        /************************************************************************/
        QDomElement nextSiblingElement(const QString & tagName = QString())
        {
            m_element = m_element.nextSiblingElement(tagName);
            return m_element;
        }

        /************************************************************************/
        //自定义xml类 -- 上一个节点
        //输入参数：
        //      name -- 节点名
        //返回参数：
        //      节点
        /************************************************************************/
        QDomElement previousSiblingElement(const QString & tagName = QString())
        {
            m_element = m_element.previousSiblingElement(tagName);
            return m_element;
        }

        /************************************************************************/
        //自定义xml类 -- 开始一个节点
        //输入参数：
        //      name -- 节点名
        /************************************************************************/
        void beginElement(const QString& name);

        /************************************************************************/
        //自定义xml类 -- 开始一个节点
        //输入参数：
        //      name -- 节点名
        /************************************************************************/
        void beginElement(const QDomElement& element)
        {
            m_element = element;
        }

        /************************************************************************/
        //自定义xml类 -- 退出该节点
        /************************************************************************/
        void endElement();

        /************************************************************************/
        //自定义xml类 -- 添加一个节点
        //输入参数：
        //      name -- 节点名
        //返回参数：
        //      节点
        /************************************************************************/
        QDomElement addElement(const QString& name);

        /************************************************************************/
        //自定义xml类 -- 删除节点
        //输入参数：
        //      name -- 节点名
        /************************************************************************/
        void removeElement(const QString& name);

        /************************************************************************/
        //自定义xml类 -- 是否存在节点
        //输入参数：
        //      name -- 节点名
        /************************************************************************/
        bool hasElement(const QString& name) const;
        /****************************/
        //键值操作
        /****************************/

        /************************************************************************/
        //自定义xml类 -- 设置键值
        //输入参数：
        //      key -- 键
        //      value -- 值
        /************************************************************************/
        void setValue(const QString& key, const QString& value);

        /************************************************************************/
        //自定义xml类 -- 读取键值
        //输入参数：
        //      key -- 键
        //      defValue -- 默认值
        //返回参数：
        //      值
        /************************************************************************/
        QString value(const QString& key, const QString& defValue = QString()) const;

        /************************************************************************/
        //自定义xml类 -- 获取文档字节流
        //返回参数：
        //      文档字节流
        /************************************************************************/
        QByteArray getByteArray() const;

        /****************************/
        //文本操作
        /****************************/
        /************************************************************************/
        //自定义xml类 -- 设置文本
        //输入参数：
        //      text -- 文本
        /************************************************************************/
        void setText(const QString& text);

        /************************************************************************/
        //自定义xml类 -- 获取文本
        //返回参数：
        //      文本
        /************************************************************************/
        QString text() const;

        /************************************************************************/
        //自定义xml类 -- 判断是否存在文本
        /************************************************************************/
        bool hasText();

        /****************************/
        //属性操作
        /****************************/
        /************************************************************************/
        //自定义xml类 -- 设置属性
        //输入参数：
        //      name -- 属性名
        //      attribute -- 属性值
        /************************************************************************/
        void setAttribute(const QString& name, const QString& attribute);

        /************************************************************************/
        //自定义xml类 -- 删除属性
        //输入参数：
        //      name -- 属性名
        /************************************************************************/
        void removeAttribute(const QString& name);

        /************************************************************************/
        //自定义xml类 -- 是否存在属性
        //输入参数：
        //      name -- 属性名
        /************************************************************************/
        bool hasAttribute(const QString& name);

        /************************************************************************/
        //自定义xml类 -- 是否存在属性
        /************************************************************************/
        bool hasAttributes();

        /************************************************************************/
        //自定义xml类 -- 获取属性
        //输入参数：
        //      name -- 属性名
        //      defAttribute -- 默认属性值
        //返回参数：
        //      属性值
        /************************************************************************/
        QString attribute(const QString& name, const QString& defAttribute = QString()) const;

        /************************************************************************/
        //自定义xml类 -- 获取属性
        //返回参数：
        //      所有属性映射表
        /************************************************************************/
        QXmlStreamAttributes attributes() const;

        /****************************/
        //其它操作
        /****************************/
        /************************************************************************/
        //自定义xml类 -- 清空
        /************************************************************************/
        void clear();

        /************************************************************************/
        //自定义xml类 -- 是否合法
        /************************************************************************/
        bool isValid() const { return m_bValid; }
    private:
        QDomDocument m_doc;//文档
        QString m_strCodecName;//编码名
        QFile m_file;//文件
        QString m_strFile;//文件名
        QString m_strRootName;//根节点
        bool m_bValid;//合法

        QDomElement m_element;//当前节点
        QIODevice::OpenMode m_mode;//打开模式
    };
}

